/**
 * Main Process MQTT Adapter - Handles MQTT messages from Electron main process
 *
 * This module receives MQTT messages from the Electron main process via stdin
 * and provides a similar interface to the original MQTT service.
 */

import readline from 'readline';

// Event emitter to handle MQTT events
import { EventEmitter } from 'events';

// Create event emitter for MQTT messages
const mqttEvents = new EventEmitter();

// Set maximum listeners to avoid memory leak warnings
mqttEvents.setMaxListeners(100);

// 创建消息缓存，用于消息去重
const messageCache = new Set();
const MESSAGE_CACHE_SIZE = 50; // 缓存最近50条消息
let messageCounter = 0; // 计数器，用于限制日志频率

let rl;

// 生成消息哈希的简单函数
function hashMessage(message) {
  let hash = 0;
  for (let i = 0; i < message.length; i++) {
    const char = message.charCodeAt(i);
    hash = ((hash << 5) - hash) + char;
    hash = hash & hash; // Convert to 32bit integer
  }
  return hash.toString();
}

// Try to set up readline interface in a safer way
try {
  // Check if process.stdin is available and readable
  if (process.stdin && process.stdin.readable) {
    rl = readline.createInterface({
      input: process.stdin,
      output: process.stdout,
      terminal: false
    });

    // Parse messages from stdin (from Electron main process)
    rl.on('line', (line) => {
      try {
        if (!line || line.trim() === '') return;

        // 使用消息哈希进行去重，避免处理完全相同的消息
        const messageHash = hashMessage(line);
        if (messageCache.has(messageHash)) {
          // 如果是相同的消息，不再重复处理
          return;
        }

        // 添加到缓存
        messageCache.add(messageHash);

        // 如果缓存过大，清理旧消息
        if (messageCache.size > MESSAGE_CACHE_SIZE) {
          const iterator = messageCache.values();
          messageCache.delete(iterator.next().value);
        }

        // 控制日志输出频率
        messageCounter++;
        if (messageCounter % 5 === 0 || !line.includes('mqtt-message')) {
          console.log(`[MQTT Adapter] Received message: ${line.substring(0, 100)}${line.length > 100 ? '...' : ''}`);
        }

        const message = JSON.parse(line);

        // Handle MQTT messages
        if (message.type === 'mqtt-message') {
          const { topic, message: messageData, packet } = message.data;

          // Convert string message back to object if it's in JSON format
          let parsedMessage;
          try {
            parsedMessage = JSON.parse(messageData);
          } catch (e) {
            parsedMessage = messageData;
          }

          // 控制日志频率，减少过多的相同主题日志
          if (messageCounter % 10 === 0 || !topic.includes('control')) {
            console.log(`[MQTT Adapter] Emitting message for topic: ${topic}`);
          }

          // Emit message event for subscribers
          mqttEvents.emit('message', topic, parsedMessage, packet);
        }
      } catch (error) {
        console.error('[MQTT Adapter] Error processing message from main process:', error);
      }
    });

    rl.on('error', (err) => {
      console.error('[MQTT Adapter] Error with readline interface:', err);
      // Try to recreate the interface if possible
      try {
        rl.close();
      } catch (e) {
        // Ignore errors when closing
      }
    });

    console.log('[MQTT Adapter] Successfully set up stdin message handler');
  } else {
    console.warn('[MQTT Adapter] Process stdin is not available or not readable');
  }
} catch (error) {
  console.error('[MQTT Adapter] Failed to set up readline interface:', error);
}

// Create a mock MQTT service that mimics the original one
export const mqttService = {
  client: {
    on: (event, callback) => {
      if (event === 'message') {
        mqttEvents.on('message', callback);
      }
      return mqttService.client;
    },
    removeListener: (event, callback) => {
      if (event === 'message') {
        mqttEvents.removeListener('message', callback);
      }
      return mqttService.client;
    }
  },

  // These methods do nothing in the node script as MQTT is handled in the main process
  connect: () => {
    console.log('[MQTT Adapter] Requesting MQTT connection from main process');
    // 如果我们能访问process.stdin，则向主进程发送连接请求
    try {
      if (process.stdout && process.stdout.write) {
        // 向主进程发送消息，请求连接MQTT
        const connectionRequest = {
          source: 'node-script',
          type: 'mqtt-action',
          action: 'connect',
          timestamp: Date.now()
        };

        // 输出特定格式的消息，主进程可以捕获
        console.log(JSON.stringify(connectionRequest));

        // 假设连接请求已发送
        return true;
      }
    } catch (error) {
      console.error('[MQTT Adapter] Failed to request MQTT connection:', error);
    }

    // 即使没有成功发送请求，也假装成功，因为实际的MQTT连接由主进程管理
    return true;
  },

  subscribe: () => {
    console.log('[MQTT Adapter] Topic subscription is managed by Electron main process');
    return true;
  },

  // For publish, we'll need to send a message back to the main process
  publish: (topic, message, options = {}) => {
    try {
      const messageStr = typeof message === 'object' ? JSON.stringify(message) : message;
      console.log(`[MQTT Adapter] Publishing message to ${topic} via main process`);

      // In a real implementation, this would send a message back to the main process
      // For now, we'll just log it as we haven't set up the reverse communication channel
      console.log(`[MQTT Adapter] Message content: ${messageStr.substring(0, 100)}${messageStr.length > 100 ? '...' : ''}`);

      return true;
    } catch (error) {
      console.error('[MQTT Adapter] Error publishing message:', error);
      return false;
    }
  },

  disconnect: () => {
    console.log('[MQTT Adapter] MQTT disconnection is managed by Electron main process');
    return true;
  },

  // Helper method to add a message handler (simplifies migration)
  onMessage: (callback) => {
    mqttEvents.on('message', callback);
    return () => mqttEvents.removeListener('message', callback);
  }
};

// Log startup
console.log('[MQTT Adapter] Main process MQTT adapter initialized');

// Clean up on exit
process.on('exit', () => {
  rl.close();
});